(ns acst.models.entry-forms
  (:use acst.config.error-config
        acst.config.success-config
        acst.utils.handle-exp)
  (:require [acst.models.db :as db]))


(defn- valid-notnull-constraint? [notnull value]
  (if (and (true? notnull) (nil? value))                    ;;notnull为true而value空即非法
    false
    true))

(defn- valid-length-constraint? [longer shorter value]
  (let [length (count value)]
    (println length value)
    (and (>= length longer) (<= length shorter))))

(defn- valid-regex-constraint? [regex value]
  (or (nil? regex)
      (not (nil? (re-matches (re-pattern regex) value)))))

(defn- find-a-form-element-error [{:keys [notnull longer shorter regex]} value]
  (->>
    (if-not (valid-regex-constraint? regex value) (:invalid-regex-value entry-form-error) nil)
    (if-not (valid-length-constraint? longer shorter value) (:invalid-length-value entry-form-error))
    (if (nil? value) nil)
    (if-not (valid-notnull-constraint? notnull value) (:invalid-notnull-value entry-form-error))))

(defn- find-whole-form-element-error
  ([form_constraint value_map] (let [value_keys (keys value_map)
                                      struct_keys (keys form_constraint)]
                                  (if (= (into #{} value_keys) (into #{} struct_keys)) ;;判断是否包含未定义的字段
                                    (find-whole-form-element-error form_constraint value_map struct_keys)
                                    (:not-allow-keys entry-form-error))))
  ([form_constraint value_map rest_keys]
    (if (= '() rest_keys)
      nil
      (let [key (first rest_keys)
            value (get value_map key)
            constraint (get form_constraint key)
            error (find-a-form-element-error constraint value)]
        (if (get-error error)
          error
          (recur form_constraint value_map (rest rest_keys)))))))

(defn- find-entry-form-error [activity_id value_map]
  (let [result (db/query (:constraint-not-found forms-constraint-error)
                         ["SELECT form_constraint FROM forms_constraint, activities
                         WHERE forms_constraint.activity_id =? AND deadline > now()" activity_id])] ;;超过deadline不允许报名
    (if (get-error result)
      result
      (let [{form_constraint :form_constraint} (first result)
            error (find-whole-form-element-error form_constraint value_map)]
        (if (get-error error)
          error
          nil)))))

(defn find-entry-forms-by-activity-id [activity_id]
  (db/query (:without-any-entry-form entry-form-error)
            ["SELECT publisher_id, username, create_date, value FROM entry_forms, users
            WHERE user_id = publisher_id AND activity_id = ?" activity_id]))

(defn insert-entry-form! [publisher_id activity_id value_map]
  (let [value_error (find-entry-form-error activity_id value_map)]
    (if (nil? value_error)
      (let [error (get-error (db/insert! :entry_forms
                                         {:publisher_id publisher_id
                                          :activity_id activity_id
                                          :value value_map}))]
            (if (nil? error)
              (:signup-success entry-form-result)
              error))
      value_error)))